﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BadHabit.Factory.Windows {

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class Main : BadHabit.WPFTools.ShapedWindow {


        internal static readonly DependencyProperty IsPopUpOpenedProperty =
            DependencyProperty.Register("IsPopUpOpened", typeof(bool), typeof(Main), new PropertyMetadata(false));

        public bool IsPopUpOpened {
            get {
                return (bool)GetValue(IsPopUpOpenedProperty);
            }
            set {
                SetValue(IsPopUpOpenedProperty, value);
            }
        }
        
      

        public TabItem SelectedTabItem {
            get {
                return tabControl.tabControl.SelectedItem as TabItem;
            }
        }

        public Main()  {
            InitializeComponent();                    
        }

        public Data.ProjectDataSet.ProjectRow CurrentProject {
            get {
                if (tabControl == null)
                    return null;
                return tabControl.Project;
            }
        }
        
        
        /// <summary>
        /// Get out of the application.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItemGetOut_Click(object sender, RoutedEventArgs e) {
            WindowState = WindowState.Minimized;
        }


        private static BadHabit.Factory.Windows.Settings settingsWindow = null;
        public static void ShowSettingsWindow(bool connectionOnly) {
            if (settingsWindow != null)
                return;

            settingsWindow = new Windows.Settings(connectionOnly);
            settingsWindow.ShowDialog();

            settingsWindow = null;
        }

        

        private void MenuItem_Click(object sender, RoutedEventArgs e) {
            ShowSettingsWindow(false);            
        }


        /// <summary>
        /// Sets the connected information at the status bar.
        /// </summary>
        public bool ConnectedStatus {
            set {
                if (value)
                    ConnectedTextBlock.Text = Properties.Resources.Connected_as + " " + Client.User.Identity.Name;
                else
                    ConnectedTextBlock.Text = Properties.Resources.Disconnected;
                SetRolesStatusBar();
                
            }
        }

        private void SetRolesStatusBar() {
            SetRolesStatusBar(TeamRoles.FACTORY_OWNER, roleStatusFACTORY_OWNER);
            SetRolesStatusBar(TeamRoles.SCRUM_MASTER, roleStatusSCRUM_MASTER);
            SetRolesStatusBar(TeamRoles.PRODUCT_OWNER, roleStatusPRODUCT_OWNER);
            SetRolesStatusBar(TeamRoles.COMMERCIAL_GUY, roleStatusCOMMERCIAL_GUY);
            SetRolesStatusBar(TeamRoles.QUALITY_ASSURANCE, roleStatusQUALITY_ASSURANCE);
            SetRolesStatusBar(TeamRoles.TEAM, roleStatusTEAM);
        }

        private void SetRolesStatusBar(TeamRoles role, Image img) {
            if (Client.UserIsInRole(role))
                img.Visibility = Visibility.Visible;
            else
                img.Visibility = Visibility.Collapsed;

        }

        /// <summary>
        /// Binds the project to the window.
        /// </summary>
        public void Bind() {
            projectListBox.Bind();               
        }

        private void window_StateChanged(object sender, EventArgs e) {
            if (this.WindowState == WindowState.Minimized)
                this.ShowInTaskbar = false;
            else
                this.ShowInTaskbar = true;
        }


        public void ChangeTaskTabView() {
            tabControl.ChangeTaskTabItem();
        }

        private void TeamEffortMenuItem_Click(object sender, RoutedEventArgs e) {
            Windows.TeamEffortReport window = new TeamEffortReport();
            window.ShowDialog();
        }

     
        private void NewProject_Click(object sender, RoutedEventArgs e) {

            // retrives the project teplate from the server
            MenuItem item = e.OriginalSource as MenuItem;
            Data.ProjectDataSet newProjectDataSet = Client.CreateNewProject(item.Header.ToString());


            CreateNewProject(newProjectDataSet);
            

        }

        

        public void CreateNewProject(Data.ProjectDataSet newProjectDataSet) {

            if (Client.ClientList.Length == 0) {
                MessageBoxResult d = Windows.Error.ShowDialog(Properties.Resources.No_clients_message, Properties.Resources.No_clients_title, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
                if (d == MessageBoxResult.Yes) {
                    Windows.TeamMemberManager w = new TeamMemberManager(true);
                    w.ShowDialog();
                }

                return;
            }

            if (newProjectDataSet == null)
                return;

            newProjectDataSet.Project[0].ProjectName = "New Project";

            if (newProjectDataSet.Project[0].HourBankMode >= 1) {
                NewMaintanceProject w = new NewMaintanceProject(newProjectDataSet);
                w.ShowDialog();
            }


            // moves to the summary panel
            tabControl.summaryTabItem.IsSelected = true;


            // if i am creating a new project, can access its reposrt yet
            tabControl.reportsTabItem.IsEnabled = false;

            Refresh(newProjectDataSet);


            projectListBox.listBox.SelectedItem = null;
            projectListBox.headerBorder.IsChecked = true;
        }

        /// <summary>
        /// When a different project was selected, upadte the tab control context.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void projectListBox_SelectedProjectChanged(object sender, BadHabit.Factory.Controls.ProjectListBox.SelectedProjectChangedEventArgs e) {
            if (e.NewProject == null)
                return;
            Refresh(e.NewProject.ProjectUId);           
        }

        public bool ProjectHasChanges {
            get {                
                if (tabControl == null)
                    return false;

                if (tabControl.DataContextAsProjectDataSet == null)
                    return false;
                                
                bool projectHasChanges = tabControl.DataContextAsProjectDataSet.HasChanges();

                bool taskHasChanges = false;
                if (tabControl.TaskDataContext == null || tabControl.TaskDataContext.DataSet == null)
                    taskHasChanges = false;
                else
                    taskHasChanges = tabControl.TaskDataContext.DataSet.HasChanges();
                
                return projectHasChanges  || taskHasChanges;
            }
        }

        public bool IsBacklogDirty {
            get {
                if (tabControl == null)
                    return false;
                if (tabControl.DataContextAsProjectDataSet == null)
                    return false;
                System.Data.DataTable dirtyTable = tabControl.DataContextAsProjectDataSet.BacklogItem.GetChanges(System.Data.DataRowState.Added | System.Data.DataRowState.Deleted);
                if (dirtyTable == null)
                    return false;
                return (dirtyTable.Rows.Count != 0);
            }
        }

        public bool IsWaiting {
            set {
                if (value) {
                    ForceCursor = true;
                    Cursor = Cursors.Wait;
                } else {
                    ForceCursor = false;
                    Cursor = Cursors.Arrow;
                }
            }
        }

        public void Refresh() {

            if (tabControl.Project == null)
                return;

            Refresh(tabControl.Project.ProjectUId);

            // refreshs the effort bar
            effortBar.Refresh();


            Client.TaskSelector.Bind();

        }

        public void Refresh(string projectUId) {

            if (ProjectHasChanges) {
                MessageBoxResult d = Windows.Error.ShowDialog(
                    Properties.Resources.Lost_changes_question, Properties.Resources.Lost_Changes, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
                if (d == MessageBoxResult.No)
                    return;
            }
                           
            Data.ProjectDataSet dsProject = Client.RetriveProject(projectUId);

            // it may had been disabled when creating new
            tabControl.IsEnabled = true;
            tabControl.reportsTabItem.IsEnabled = true;

            Refresh(dsProject);

            // sets the taskpanel to ISENABLE, cuz it might had been setted to FALSE when backlog was dirty
            Controls.TaskPanelBase taskPanel = tabControl.taskTabItem.Content as Controls.TaskPanelBase;
            if (taskPanel != null) {
                taskPanel.IsEnabled = true;

            }

            


        }

       
        
        public void Refresh(Data.ProjectDataSet dsProject) {
            
            dsProject.ConvertToVisibleBacklog();

            dsProject.SizeType.Merge(Client.BacklogItemSizes.SizeType, false);
            dsProject.SizeType.AcceptChanges();

            AddClientContactRoleColumn(dsProject);
            BadHabit.Factory.Converters.SprintBySprintUIdConverter.ProjectDataSet = dsProject;

            Controls.TaskPanelBase taskPanel = tabControl.taskTabItem.Content as Controls.TaskPanelBase;



            if (taskPanel != null) {
                // if is a refresh at the same project, then maintain the seleted item
                bool maintainSelectedItem = false;
                if(tabControl.Project!=null)
                    maintainSelectedItem = tabControl.Project.ProjectUId.Equals(dsProject.Project[0].ProjectUId);
                taskPanel.SuspendFilter(maintainSelectedItem);
            }


            // THIS NEED TO BE CALLED FIRST OF tabControl.ChangeDataContext
            // OTHERWISE THE TASKDATAGRID LOSES THE TaskAssignee COMBOBOX SELECTION
            UpdateProjectMemberList(dsProject);

            
            tabControl.ChangeDataContext(dsProject);


            UpdateUnitList();

            UpdateProposalList();

            UpdateVisibleBacklogItemList();


            if (taskPanel != null)
                taskPanel.ResumeFilter();

            

        }

        
        /// <summary>
        /// Filters the project team members according the Project Access Mode.
        /// </summary>
        private void UpdateProjectMemberList(Data.ProjectDataSet dsProject) {
            if (dsProject == null)
                return;

            if (dsProject.Project.Count == 0)
                return;

            // only team members can work
            if (dsProject.Project[0].AccessMode == (short)ProjectAccessMode.ALL_SEE_TEAM_WORK)
                Client.ProjectMemberList = Client.GetOnlyRoleMembers(dsProject, true);
            else
                Client.ProjectMemberList = Client.GetOnlyRoleMembers(dsProject, false);
        }
  

      


                

        private void UpdateUnitList() {
            Client.UnitList = tabControl.DataContextAsProjectDataSet.BacklogItemUnit.DefaultView;
            BadHabit.Factory.Converters.UnitNameConverter.UnitList = tabControl.DataContextAsProjectDataSet.BacklogItemUnit;
        }

        private void UpdateProposalList() {
            Client.ProposalList = tabControl.DataContextAsProjectDataSet.Proposal.DefaultView;            
        }

        private void UpdateVisibleBacklogItemList() {


            
            if (tabControl.DataContextAsProjectDataSet == null)
                return;

            // SET HER TO SHOW ONLY VISIBLE ITEMS
            string rowFilter = "IsVisible=1";

            tabControl.DataContextAsProjectDataSet.VisibleBacklogItem.DefaultView.RowFilter = rowFilter;
            tabControl.DataContextAsProjectDataSet.VisibleBacklogItem.DefaultView.Sort = "BacklogItemNumber, SprintNumber";

            // need to do this in order to update the MOVE TO.. context Menu
            Client.VisibleBacklogItemList = tabControl.DataContextAsProjectDataSet.VisibleBacklogItem.DefaultView;
            
        }





        private void AddClientContactRoleColumn(Data.ProjectDataSet dsProject) {
            if (!dsProject.ProjectRole.Columns.Contains("ClientContactRole"))
                dsProject.ProjectRole.Columns.Add("ClientContactRole", typeof(bool));
            foreach (Data.ProjectDataSet.ProjectRoleRow role in dsProject.ProjectRole) {
                role["ClientContactRole"] = (role.BacklogItemUnitRowParent.Type != (short)TeamRoles.CLIENT_CONTACT);
                role.AcceptChanges();
            }            
        }



       
        public void Save() {

            

            if (tabControl.DataContextAsProjectDataSet == null)
                return;
                        
            // if project was changed, saved it
            if (tabControl.DataContextAsProjectDataSet.HasChanges())
                if (!Client.SaveProject(tabControl.DataContextAsProjectDataSet))
                    return;

            // if the save was sucefull...acceptd my dataset changes
            tabControl.DataContextAsProjectDataSet.AcceptChanges();
            
            // if i am creating a new project, can access its reposrt yet, now it can
            tabControl.reportsTabItem.IsEnabled = true;

            // if the tasks was changed, save it
            if (tabControl.TaskDataContext.DataSet.HasChanges())
                if (!Client.SaveTasks(tabControl.TaskDataContext))
                    return;

            // if the save was sucefull...acceptd my dataset changes
            tabControl.TaskDataContext.DataSet.AcceptChanges();

            

        }



        private void PART_MinimizeButton_MouseDown(object sender, MouseButtonEventArgs e) {
            if(ProjectHasChanges)
                Save();
            this.WindowState = WindowState.Minimized;
        }

        private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = ProjectHasChanges;
            e.Handled = true;
        }

        private void Save_Executed(object sender, ExecutedRoutedEventArgs e) {
            Save();
        }

        private void Refresh_Executed(object sender, ExecutedRoutedEventArgs e) {
            Refresh();
        }

        private void Refresh_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            e.CanExecute = (tabControl.DataContextAsProjectDataSet != null);
        }

        private void Undo_Executed(object sender, ExecutedRoutedEventArgs e) {
            Undo();

        }

        public void Undo() {


            if (tabControl == null)
                return;

            tabControl.TaskDataContext.DataSet.RejectChanges();

            tabControl.DataContextAsProjectDataSet.RejectChanges();


            Data.ProjectDataSet newContext = new BadHabit.Factory.Data.ProjectDataSet();
            tabControl.DataContextAsProjectDataSet.CleanUpVisibleBacklog();
            newContext.Merge(tabControl.DataContextAsProjectDataSet);

            Refresh(newContext);
        }

        private void window_Loaded(object sender, RoutedEventArgs e) {
            effortBar.Refresh();
            PART_TitleBar.MouseLeftButtonDown += new MouseButtonEventHandler(OnTitleBarMouseLeftDown);

    
        }

        private void teamMemberMenuItem_Click(object sender, RoutedEventArgs e) {
            Windows.TeamMemberManager w = new TeamMemberManager(false);
            w.ShowDialog();
        }

        private void productOwnersMenuItem_Click(object sender, RoutedEventArgs e) {
            Windows.TeamMemberManager w = new TeamMemberManager(true);
            w.ShowDialog();
            /*
            Windows.ProductOwnerManager w = new ProductOwnerManager();
            if (w.CanReadFromDataBase)
                w.ShowDialog();
            else
                Windows.Error.ShowAlert("Your Factory is using the Microsoft Exchange as Product Owners repository.\n\nYou can not manage your contact from here.");
             */ 
        }



        /// <summary>
        /// If was a drag, drag it, otherwize changes it states.
        /// </summary>
        /// <param name="e"></param>
        protected void OnTitleBarMouseLeftDown(object sender, MouseButtonEventArgs e) {
            if (e.ClickCount >= 2)
                IsMaximized = !IsMaximized;
            else {
                this.DragMove();
            }
        }

        private void aboutMenuItem_Click(object sender, RoutedEventArgs e) {
            Windows.About w = new Windows.About();
            w.Show();
        }

        
        private void ViewTeamAllocation_Executed(object sender, ExecutedRoutedEventArgs e) {
            Windows.TeamAllocation w = new TeamAllocation();
            w.Show();
        }

        private void helpMenuItem_Click(object sender, RoutedEventArgs e) {
            Helper.OpenOSWindow("http://www.scrum-factory.com/en-us/HowDoI/HowDoI.aspx");
        }

        private void ProjectPerformanceMenuItem_Click(object sender, RoutedEventArgs e) {
            Windows.ProjectPerformanceReport w = new ProjectPerformanceReport();
            w.Show();
        }
       
        
    }
}
